/**
 * @file 密码工具模块
 * @description 提供密码生成、加密、解密和强度检测功能
 * @author AI Assistant
 * @version 2.0.0
 * @since 2025-10-22
 * @updated 2025-10-31 - Removed master password, using fixed salt for encryption
 */

import crypto from 'node:crypto'

/**
 * 固定盐值 - 用于所有密码加密
 * 注意：这是一个常量盐值，用于简化密码管理器的使用
 */
const FIXED_SALT = Buffer.from('fieldano-password-manager-v2-2025', 'utf8')

/**
 * 固定加密密钥 - 从应用标识派生
 * 注意：实际应用中应该使用更安全的密钥管理方案
 */
const ENCRYPTION_KEY = crypto.pbkdf2Sync(
  'fieldano-app-encryption-key-v2',
  FIXED_SALT,
  100_000,
  32,
  'sha256'
)

/**
 * 加密结果类型
 */
export interface EncryptionResult {
  encryptedData: string
  iv: string
  salt: string
  authTag: string
}

/**
 * 解密参数类型
 */
export interface DecryptionParams {
  encryptedData: string
  iv: string
  salt: string
  authTag: string
}

/**
 * 加密密码 - 使用固定盐值
 */
export function encryptPassword(password: string): EncryptionResult {
  // 生成随机初始化向量（IV仍然需要随机以确保相同密码加密结果不同）
  const iv = crypto.randomBytes(16)

  // 使用 AES-256-GCM 加密
  const cipher = crypto.createCipheriv('aes-256-gcm', ENCRYPTION_KEY, iv)
  let encrypted = cipher.update(password, 'utf8', 'hex')
  encrypted += cipher.final('hex')

  // 获取认证标签
  const authTag = cipher.getAuthTag()

  return {
    encryptedData: encrypted,
    iv: iv.toString('hex'),
    salt: FIXED_SALT.toString('hex'),
    authTag: authTag.toString('hex')
  }
}

/**
 * 解密密码 - 使用固定盐值
 */
export function decryptPassword(params: DecryptionParams): string {
  try {
    // 将十六进制字符串转换回 Buffer
    const iv = Buffer.from(params.iv, 'hex')
    const authTag = Buffer.from(params.authTag, 'hex')

    // 使用 AES-256-GCM 解密
    const decipher = crypto.createDecipheriv('aes-256-gcm', ENCRYPTION_KEY, iv)
    decipher.setAuthTag(authTag)

    let decrypted = decipher.update(params.encryptedData, 'hex', 'utf8')
    decrypted += decipher.final('utf8')

    return decrypted
  } catch (error) {
    console.error('解密失败:', error)
    throw new Error('密码解密失败')
  }
}

/**
 * 生成安全的随机密码
 */
export function generateSecurePassword(length = 16): string {
  const bytes = crypto.randomBytes(length)
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*'
  return Array.from(bytes, b => chars[b % chars.length]).join('')
}

/**
 * 计算密码强度
 */
export function calculatePasswordStrength(password: string): {
  score: number
  level: 'weak' | 'fair' | 'good' | 'strong'
  feedback: string[]
} {
  let score = 0
  const feedback: string[] = []

  // 长度检查
  if (password.length >= 8) score += 1
  else feedback.push('密码长度至少需6位')

  if (password.length >= 12) score += 1

  // 字符类型检查
  if (/[a-z]/.test(password)) score += 1
  else feedback.push('需要包含小写字母')

  if (/[A-Z]/.test(password)) score += 1
  else feedback.push('需要包含大写字母')

  if (/[0-9]/.test(password)) score += 1
  else feedback.push('需要包含数字')

  if (/[^a-zA-Z0-9]/.test(password)) score += 1
  else feedback.push('需要包含特殊字符')

  // 确定强度等级
  let level: 'weak' | 'fair' | 'good' | 'strong'
  if (score <= 2) level = 'weak'
  else if (score <= 3) level = 'fair'
  else if (score <= 4) level = 'good'
  else level = 'strong'

  return { score, level, feedback }
}
